<?php
namespace Trawind\NetSuite\Repository;

use Trawind\NetSuite\PHPToolkit\TokenPassportGenerator;
use Trawind\NetSuite\PHPToolkit\NetSuiteService;
use Trawind\NetSuite\PHPToolkit\GetDataCenterUrlsRequest;
use Trawind\NetSuite\PHPToolkit\GetServerTimeRequest;
use Trawind\NetSuite\PHPToolkit\GetRequest;
use Trawind\NetSuite\PHPToolkit\GetAllRequest;
use Trawind\NetSuite\PHPToolkit\SubsidiarySearchBasic;
use Trawind\NetSuite\PHPToolkit\SearchRequest;
use Trawind\NetSuite\PHPToolkit\SearchMoreWithIdRequest;
use Trawind\NetSuite\PHPToolkit\DeleteRequest;
use Trawind\NetSuite\PHPToolkit\RecordRef;
use Trawind\NetSuite\PHPToolkit\GetAllRecord;
use Trawind\NetSuite\PHPToolkit\GetAllRecordType;
use Trawind\NetSuite\PHPToolkit\AddRequest;
use Trawind\NetSuite\PHPToolkit\UpdateRequest;

class Common {

    private $endpoint = '2018_1';

    private $host = 'https://webservices.netsuite.com';

    public $service;

    public $type = '';

    public function __construct($config=null)
    {
        $this->service = $this->connect($config);
    }

    /**
     * @param null $config
     * @return NetSuiteService
     */
    public function connect($config=null)
    {
        if (!$config) {
            $config = config('netsuite');
        }
        $params = [];
        $params['config'] = [
            'endpoint' => $config['endpoint'] ?? $this->endpoint,
            'host' => $config['host'] ?? $this->host,
            'account' => $config['account'],
            'appid' => $config['appid'],
        ];
        $service = new NetSuiteService(null, $params);
        $tokenConfig = [
            'account' => $config['account'],
            'consumer_key' => $config['consumer_key'],
            'consumer_secret' => $config['consumer_secret'],
            'token' => $config['token'],
            'token_secret' => $config['token_secret'],
        ];
        $generator = new TokenPassportGenerator($tokenConfig);
        $params = new GetDataCenterUrlsRequest();

        // get urls
        $params->account = $config['account'];
        $response = $service->getDataCenterUrls($params);
        $webservicesDomain = $response->getDataCenterUrlsResult->dataCenterUrls->webservicesDomain;

        // set url
        $service->setHost($webservicesDomain);
        // set token
        $service->setTokenGenerator($generator);
        return $service;
    }

    /**
     * @return mixed
     * @throws \Exception
     */
    public function index()
    {
        $this->service->setSearchPreferences(true, $this->pageSize);
        if (isset($this->search) && $this->search) {
            $getSearch = new $this->search;

            $request = new SearchRequest();
            $request->searchRecord = $getSearch;
            $response = $this->service->search($request);
            if (!$response->searchResult->status->isSuccess) {
                throw new \Exception($response->searchResult->status->statusDetail[0]->message);
            }
            $data = [];
            $index = 0;
            foreach ($response->searchResult->recordList->record as $value) {
                foreach ($this->searchFields as $searchField) {
                    $data[$index][$searchField] = $value->$searchField;
                }
                $index++;
            }
            $pageIndex = $response->searchResult->pageIndex;
            $totalPages = $response->searchResult->totalPages;
            $request = new SearchMoreWithIdRequest();
            for ($i = $pageIndex + 1; $i <= $totalPages; $i++) {
                $request->searchId = $response->searchResult->searchId;
                $request->pageIndex = $i;
                $response = $this->service->searchMoreWithId($request);
                if (!$response->searchResult->status->isSuccess) {
                    throw new \Exception($response->searchResult->status->statusDetail[0]->message);
                }
                foreach ($response->searchResult->recordList->record as $value) {
                    foreach ($this->searchFields as $searchField) {
                        $data[$index][$searchField] = $value->$searchField;
                    }
                    $index++;
                }
            }
        } else {
            $request = new GetAllRequest();
            $request->record = new GetAllRecord();
            $request->record->recordType = $this->type;
            $response = $this->service->getAll($request);
            if (!$response->getAllResult->status->isSuccess) {
                throw new \Exception($response->getAllResult->status->statusDetail[0]->message);
            }
            $data = [];
            $index = 0;
            foreach ($response->getAllResult->recordList->record as $value) {
                foreach ($this->searchFields as $searchField) {
                    $data[$index][$searchField] = $value->$searchField;
                }
                $index++;
            }
        }

        return $data;
    }

    /**
     * @param $data
     * @return mixed
     * @throws \Exception
     */
    public function store($data)
    {
        $object = new $this->store;

        // set data
        $object = $this->setData($object, $data);

        $request = new AddRequest();
        $request->record = $object;
        $response = $this->service->add($request);
        if (!$response->writeResponse->status->isSuccess) {
            throw new \Exception($response->writeResponse->status->statusDetail[0]->message);
        }
        return $response->writeResponse->baseRef->internalId;
    }

    /**
     * @param $id
     * @param $data
     * @return mixed
     * @throws \Exception
     */
    public function update($id, $data)
    {
        $this->service = $this->connect();
        $object = $this->show($id);

        $object = $this->setData($object, $data);

        $request = new UpdateRequest();
        $request->record = $object;

        $this->service->setPreferences(false, false, false, true);

        $response = $this->service->update($request);
        if (!$response->writeResponse->status->isSuccess) {
            throw new \Exception($response->writeResponse->status->statusDetail[0]->message);
        }
        return $response->writeResponse->baseRef->internalId;
    }

    /**
     * @param $id
     * @return mixed
     * @throws \Exception
     */
    public function show($id)
    {
        $request = new GetRequest();
        $request->baseRef = new RecordRef();
        $request->baseRef->internalId = $id;
        $request->baseRef->type = $this->type;
        $response = $this->service->get($request);
        if (!$response->readResponse->status->isSuccess) {
            throw new \Exception($response->writeResponse->status->statusDetail[0]->message);
        }
        return $response->readResponse->record;
    }

    /**
     * @param $id
     * @return mixed
     * @throws \Exception
     */
    public function destory($id)
    {
        $request = new DeleteRequest();
        $request->baseRef = new RecordRef();
        $request->baseRef->internalId = $id;
        $request->baseRef->type = $this->type;
        $response = $this->service->delete($request);
        if (!$response->writeResponse->status->isSuccess) {
            throw new \Exception($response->writeResponse->status->statusDetail[0]->message);
        }
        return $response->writeResponse->baseRef->internalId;
    }

    protected function setData($object, $data)
    {

    }
}
